#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
样本数据加载器集成测试
使用真实样本数据文件进行测试
"""

import os
import unittest
import logging
from src.text.sample_data_loader import SampleDataLoader, get_sample_data_loader

# 设置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


class IntegrationTestSampleDataLoader(unittest.TestCase):
    """
    SampleDataLoader的集成测试类
    使用真实的样本数据文件进行测试
    """
    
    def setUp(self):
        """
        测试前的准备工作
        """
        # 真实样本数据文件路径
        self.sample_data_path = os.path.join(
            os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
            'data', '样本数据表.csv'
        )
        
        # 检查文件是否存在
        if not os.path.exists(self.sample_data_path):
            logger.warning(f"样本数据文件不存在: {self.sample_data_path}")
            self.skipTest("样本数据文件不存在，跳过集成测试")
        
        # 创建SampleDataLoader实例
        self.loader = SampleDataLoader(self.sample_data_path)
    
    def tearDown(self):
        """
        测试后的清理工作
        """
        # 重置全局单例，避免测试之间的相互影响
        global sample_data_loader_instance
        sample_data_loader_instance = None
    
    def test_real_data_loading(self):
        """
        测试加载真实样本数据
        """
        logger.info("测试加载真实样本数据...")
        
        # 验证数据已加载
        self.assertTrue(self.loader.is_data_loaded(), "样本数据加载失败")
        
        # 验证样本数量（根据之前搜索的结果，应该有359条记录）
        sample_count = self.loader.get_sample_count()
        logger.info(f"样本数据记录数: {sample_count}")
        self.assertGreater(sample_count, 0, "样本数据记录数应为正数")
        
        # 验证索引大小
        index_size = self.loader.get_index_size()
        logger.info(f"索引条目数: {index_size}")
        self.assertGreaterEqual(index_size, 0, "索引条目数应为非负数")
        
        # 验证索引效率
        self.assertLessEqual(index_size, sample_count, "索引条目数不应超过样本记录数")
    
    def test_column_names_integrity(self):
        """
        测试列名完整性
        """
        logger.info("测试列名完整性...")
        
        # 获取列名
        columns = self.loader.get_column_names()
        logger.info(f"列名列表: {columns}")
        
        # 验证关键字段存在
        expected_columns = ['视频ID', '达人昵称', '视频描述']
        missing_columns = [col for col in expected_columns if col not in columns]
        
        # 如果关键字段缺失，记录警告但不直接失败（因为文件格式可能有变化）
        if missing_columns:
            logger.warning(f"警告: 缺少以下关键字段: {missing_columns}")
        else:
            logger.info("所有关键字段都存在")
        
        # 至少应该有一些列
        self.assertGreater(len(columns), 0, "数据文件应该至少有一个列")
    
    def test_get_sample_by_index(self):
        """
        测试根据索引获取样本数据
        """
        logger.info("测试根据索引获取样本数据...")
        
        # 获取前几个样本数据
        sample_indices = [0, 1, 5, 10]  # 测试几个不同的索引
        valid_samples = 0
        
        for idx in sample_indices:
            sample = self.loader.get_sample_by_index(idx)
            if sample:
                valid_samples += 1
                logger.info(f"索引 {idx} 的样本数据: {list(sample.keys())[:3]}...")  # 只显示前3个键
                
                # 验证数据格式
                self.assertIsInstance(sample, dict, "样本数据应为字典格式")
                self.assertGreater(len(sample), 0, "样本数据不应为空")
        
        # 至少应该有一个有效的样本
        self.assertGreater(valid_samples, 0, "应该至少能获取一个有效样本")
    
    def test_search_functionality(self):
        """
        测试搜索功能
        """
        logger.info("测试搜索功能...")
        
        # 搜索一些常见的内容
        search_terms = [
            "视频",  # 很可能在描述中出现
            "达人",  # 很可能在达人相关字段中出现
            "1",     # 很可能在ID或数字字段中出现
        ]
        
        for term in search_terms:
            results = self.loader.search_samples(term)
            logger.info(f"搜索 '{term}' 找到 {len(results)} 条结果")
            
            # 检查结果格式
            if results:
                self.assertIsInstance(results, list, "搜索结果应为列表格式")
                self.assertIsInstance(results[0], dict, "搜索结果项应为字典格式")
    
    def test_sample_statistics(self):
        """
        测试样本统计信息
        """
        logger.info("测试样本统计信息...")
        
        # 获取统计信息
        stats = self.loader.get_sample_statistics()
        
        # 验证统计信息格式
        self.assertIsInstance(stats, dict, "统计信息应为字典格式")
        
        # 验证关键字段
        expected_keys = ['total_records', 'index_size', 'last_loaded_time', 'file_path', 'column_count']
        for key in expected_keys:
            self.assertIn(key, stats, f"统计信息应包含键 '{key}'")
        
        # 验证记录数
        self.assertGreater(stats['total_records'], 0, "总记录数应为正数")
        
        # 验证列统计
        self.assertIn('column_statistics', stats, "统计信息应包含列统计")
        self.assertIsInstance(stats['column_statistics'], dict, "列统计应为字典格式")
        
        # 打印部分统计信息
        logger.info(f"统计信息摘要: 总记录数={stats['total_records']}, "
                   f"列数={stats['column_count']}, 索引大小={stats['index_size']}")
    
    def test_singleton_pattern(self):
        """
        测试单例模式
        """
        logger.info("测试单例模式...")
        
        # 获取单例实例
        instance1 = get_sample_data_loader(self.sample_data_path)
        instance2 = get_sample_data_loader()
        
        # 验证是同一个实例
        self.assertIs(instance1, instance2, "get_sample_data_loader() 应返回相同实例")
        
        # 验证数据已加载
        self.assertTrue(instance1.is_data_loaded(), "单例实例的数据应已加载")
        
        # 验证实例的数据加载状态与直接创建的实例一致
        self.assertEqual(instance1.get_sample_count(), self.loader.get_sample_count(), 
                         "单例实例与直接创建的实例的样本数量应一致")
    
    def test_refresh_functionality(self):
        """
        测试刷新功能
        """
        logger.info("测试刷新功能...")
        
        # 获取初始加载时间
        initial_time = self.loader.get_last_loaded_time()
        logger.info(f"初始加载时间: {initial_time}")
        
        # 刷新数据
        result = self.loader.refresh_data()
        self.assertTrue(result, "刷新数据应成功")
        
        # 获取刷新后的时间
        refreshed_time = self.loader.get_last_loaded_time()
        logger.info(f"刷新后时间: {refreshed_time}")
        
        # 验证时间已更新
        self.assertIsNotNone(refreshed_time, "刷新后时间不应为None")
        
        # 注意：由于文件未变更，实际时间可能相同，但refresh_data()方法应返回True
        # 我们只验证方法执行成功即可


# 重置全局单例，避免测试之间的影响
sample_data_loader_instance = None


if __name__ == '__main__':
    # 运行集成测试
    logger.info("开始样本数据加载器集成测试...")
    unittest.main()